package com.yunhe.merchants.service.impl;

import com.alibaba.fastjson.JSON;
import com.yunhe.common.model.ResultObject;
import com.yunhe.common.model.authority.Organization;
import com.yunhe.common.util.DateTimeUtils;
import com.yunhe.common.util.RedisClient;
import com.yunhe.common.util.StringUtil;
import com.yunhe.merchants.client.AuthorityClient;
import com.yunhe.merchants.constant.MyProjectConsts;
import com.yunhe.merchants.model.*;
import com.yunhe.merchants.repository.MyProjectRepository;
import com.yunhe.merchants.repository.ProcessStatusRepository;
import com.yunhe.merchants.service.IPlanService;
import com.yunhe.merchants.service.IStatisticsAnalysisService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import com.yunhe.common.util.CollectionUtil;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @ClassName: StatisticsAnalysisServiceImpl
 * @Description:
 * @author: GongDaCheng
 * @Date: 10:19 2021/5/17
 */
@Service
public class StatisticsAnalysisServiceImpl implements IStatisticsAnalysisService {

    @Autowired
    private RedisClient redisClient;
    @Autowired
    private AuthorityClient authorityClient;
    @Autowired
    ProcessStatusRepository processStatusRepository;
    @Autowired
    private MyProjectRepository myProjectRepository;

    @Autowired
    private IPlanService planService;

    static List<String> companyStatusList = new ArrayList<>();

    static {
        companyStatusList = Arrays.asList(
                MyProjectConsts.COMPANY_STATUS.Intention.value(),
                MyProjectConsts.COMPANY_STATUS.Phone.value(),
                MyProjectConsts.COMPANY_STATUS.Visit.value(),
                MyProjectConsts.COMPANY_STATUS.FollowUp.value(),
                MyProjectConsts.COMPANY_STATUS.Sign.value(),
                MyProjectConsts.COMPANY_STATUS.Pay.value(),
                MyProjectConsts.COMPANY_STATUS.License.value(),
                MyProjectConsts.COMPANY_STATUS.Success.value(),
                MyProjectConsts.COMPANY_STATUS.Park.value(),
                MyProjectConsts.COMPANY_STATUS.LeaveSoon.value(),
                MyProjectConsts.COMPANY_STATUS.Leave.value(),
                MyProjectConsts.COMPANY_STATUS.Fail.value()
        );
    }

    @Override
    public CustomerStatistics getCustomerStatistics(Long userId, String year, String month) {
        CustomerStatistics customerStatistics = new CustomerStatistics();
        customerStatistics.setYear(year);
        customerStatistics.setMonth(month);
        List<Long> orgIds = subOrg(userId);
        String startTime = DateTimeUtils.getFirstDayOfMonth(Integer.parseInt(year), Integer.parseInt(month));
        String endTime = DateTimeUtils.getLastDayOfMonth(Integer.parseInt(year), Integer.parseInt(month));
        //1.意向签约数、正式签约数
        List<String> intentionStatusList = Arrays.asList(
                MyProjectConsts.COMPANY_STATUS.Intention.value(),
                MyProjectConsts.COMPANY_STATUS.Phone.value(),
                MyProjectConsts.COMPANY_STATUS.Visit.value(),
                MyProjectConsts.COMPANY_STATUS.FollowUp.value(),
                MyProjectConsts.COMPANY_STATUS.Sign.value(),
                MyProjectConsts.COMPANY_STATUS.Pay.value(),
                MyProjectConsts.COMPANY_STATUS.License.value(),
                MyProjectConsts.COMPANY_STATUS.Park.value(),
                MyProjectConsts.COMPANY_STATUS.LeaveSoon.value(),
                MyProjectConsts.COMPANY_STATUS.Leave.value(),
                MyProjectConsts.COMPANY_STATUS.Fail.value()
        );
        long intentCount = 0;
        List<Map<String, Integer>> maps = myProjectRepository.getCountByOrgIdAndTime(orgIds,
                intentionStatusList, startTime, endTime);
        if(!CollectionUtil.isEmpty(maps)){
            IntSummaryStatistics summaryStatistics = maps.stream().collect(
                    Collectors.summarizingInt(e -> {
                        return Integer.valueOf(((Map) e).get("countNum").toString());
                    }));
            intentCount = summaryStatistics.getSum();
        }
        //2.来访量、来电量
        int visitCount = processStatusRepository.getCountByOrgIdAndTime(orgIds, null, MyProjectConsts.COMPANY_STATUS.Visit.value(), startTime, endTime);
        int phoneCount = processStatusRepository.getCountByOrgIdAndTime(orgIds, null, MyProjectConsts.COMPANY_STATUS.Phone.value(), startTime, endTime);
        customerStatistics.setVisitorCount(visitCount);
        customerStatistics.setCallerCount(phoneCount);
        //正式签约数据
        List<String> successStatusList = Arrays.asList(MyProjectConsts.COMPANY_STATUS.Success.value(),
                MyProjectConsts.COMPANY_STATUS.LeaveSoon.value(),
                MyProjectConsts.COMPANY_STATUS.Leave.value());
        int successCount  = myProjectRepository.getPhoneCountByOrgIdAndTime(orgIds,successStatusList,MyProjectConsts.COMPANY_STATUS.Success.value());
        customerStatistics.setFormalSignCount(successCount);
        customerStatistics.setIntentionSignCount(intentCount+successCount);
        return customerStatistics;
    }

    @Override
    public SalesFunnel getSalesFunnel(Long userId) {
        SalesFunnel salesFunnel = new SalesFunnel();
        List<Long> orgIds = subOrg(userId);
        List<String> statusList = companyStatusList;

        //意向项目
        List<String> intentionStatusList = Arrays.asList(
                MyProjectConsts.COMPANY_STATUS.Intention.value(),
                MyProjectConsts.COMPANY_STATUS.Phone.value(),
                MyProjectConsts.COMPANY_STATUS.Visit.value(),
                MyProjectConsts.COMPANY_STATUS.FollowUp.value(),
                MyProjectConsts.COMPANY_STATUS.Sign.value(),
                MyProjectConsts.COMPANY_STATUS.Pay.value(),
                MyProjectConsts.COMPANY_STATUS.License.value(),
                MyProjectConsts.COMPANY_STATUS.Park.value(),
                MyProjectConsts.COMPANY_STATUS.LeaveSoon.value(),
                MyProjectConsts.COMPANY_STATUS.Leave.value(),
                MyProjectConsts.COMPANY_STATUS.Fail.value()
        );
        long intentCount = 0;
        List<Map<String, Integer>> maps = myProjectRepository.getCountByOrgIdAndTime(orgIds, intentionStatusList, null, null);
        if(!CollectionUtil.isEmpty(maps)){
            IntSummaryStatistics summaryStatistics = maps.stream().collect(
                    Collectors.summarizingInt(e -> {
                        return Integer.valueOf(((Map) e).get("countNum").toString());
                    }));
            intentCount = summaryStatistics.getSum();
        }
        //查询电话来访
        statusList.remove(Arrays.asList(MyProjectConsts.COMPANY_STATUS.Intention.value()));
        int phoneCount  = myProjectRepository.getPhoneCountByOrgIdAndTime(orgIds,statusList,MyProjectConsts.COMPANY_STATUS.Phone.value());
        salesFunnel.setCallerCount(phoneCount);
        //客户来访量
        statusList.remove(Arrays.asList(MyProjectConsts.COMPANY_STATUS.Phone.value()));
        int visitCount  = myProjectRepository.getPhoneCountByOrgIdAndTime(orgIds,statusList,MyProjectConsts.COMPANY_STATUS.Visit.value());
        salesFunnel.setVisitorCount(visitCount);
        // 后续跟进
        statusList.remove(Arrays.asList(MyProjectConsts.COMPANY_STATUS.Visit.value()));
        int followUpCount  = myProjectRepository.getPhoneCountByOrgIdAndTime(orgIds,statusList,MyProjectConsts.COMPANY_STATUS.FollowUp.value());
        salesFunnel.setFollowCount(followUpCount);
        // 签订合同
        statusList.remove(Arrays.asList(MyProjectConsts.COMPANY_STATUS.FollowUp.value()));
        int signCount  = myProjectRepository.getPhoneCountByOrgIdAndTime(orgIds,statusList,MyProjectConsts.COMPANY_STATUS.Sign.value());
        salesFunnel.setSignContractCount(signCount);
        //成功项目
        List<String> successStatusList = Arrays.asList(MyProjectConsts.COMPANY_STATUS.Success.value(),
                MyProjectConsts.COMPANY_STATUS.LeaveSoon.value(),
                MyProjectConsts.COMPANY_STATUS.Leave.value());
        int successCount  = myProjectRepository.getPhoneCountByOrgIdAndTime(orgIds,successStatusList,MyProjectConsts.COMPANY_STATUS.Success.value());
        salesFunnel.setSuccessProjectCount(successCount);
        salesFunnel.setIntentionProjectCount(intentCount+successCount);
        return salesFunnel;
    }

    @Override
    public List<ChannelSourceData> getChannelSource(Long userId) {
        List<Long> orgIds = subOrg(userId);
        return myProjectRepository.getChannelSourse(orgIds);
    }

    @Override
    public List<PersonalPlanComplete> planCompletion(Long stationId, Long userId, String year, String month) {
        List<PersonalPlanComplete> personalPlanCompletes = new ArrayList<>();
        List<Long> orgIds = subOrg(userId);
        //通过园区以及部门查询所有所有业务员
        List<Map> maps = getSalesMan(stationId,orgIds,"salesman");
        if (!CollectionUtil.isEmpty(maps)) {
            maps.stream().forEach(map -> {
                PersonalPlanComplete personalPlanComplete = new PersonalPlanComplete();
                personalPlanComplete.setSalesmanId(Long.valueOf(map.get("userId").toString()));
                personalPlanComplete.setName(map.get("userName").toString());
                Statistics statistics = planService.salesmanPlanStatistics(Long.valueOf(map.get("orgId").toString()), Long.valueOf(map.get("userId").toString()),
                        MyProjectConsts.Time_Type.Month.value(), year, null, month);
                Double rateTotal = 0.0;
                if(statistics != null){
                    if(statistics.getCallerCount() != null && statistics.getCallerCount().getCurrentRate() != null){
                        rateTotal += statistics.getCallerCount().getCurrentRate();
                    }
                    if(statistics.getContractedArea() != null && statistics.getContractedArea().getCurrentRate() != null){
                        rateTotal += statistics.getContractedArea().getCurrentRate();
                    }
                    if(statistics.getNetworkPromotionCount() != null && statistics.getNetworkPromotionCount().getCurrentRate() != null){
                        rateTotal += statistics.getNetworkPromotionCount().getCurrentRate();
                    }
                    if(statistics.getVisitorCount() != null && statistics.getVisitorCount().getCurrentRate() != null){
                        rateTotal += statistics.getVisitorCount().getCurrentRate();
                    }
                }
                if(!rateTotal.isNaN()){
                    BigDecimal divide = BigDecimal.valueOf(rateTotal).divide(BigDecimal.valueOf(4));
                    double avgRate = divide == null ?0.0:divide.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
                    personalPlanComplete.setCompletionRate(avgRate);
                }
                personalPlanCompletes.add(personalPlanComplete);
            });
        }
        //排序
        if(!CollectionUtil.isEmpty(personalPlanCompletes)){
            personalPlanCompletes.sort(Comparator.comparing(h -> h.getCompletionRate()));
            Collections.reverse(personalPlanCompletes);
        }
        return personalPlanCompletes;
    }

    private List<Map> getSalesMan(Long stationId, List<Long> orgIds, String salesman) {
        List<Map> result = new ArrayList<>();
        ResponseEntity<ResultObject> responseEntity = authorityClient.getUserByStationIdAndOrg(stationId,orgIds,"salesman");
        if(responseEntity != null){
            if(responseEntity.getStatusCode().is2xxSuccessful()){
                Object results = responseEntity.getBody().getResults();
                List<Map> maps = JSON.parseArray(JSON.toJSONString(results),Map.class);
                if(!CollectionUtil.isEmpty(maps)){
                    result.addAll(maps);
                }
            }
        }
        //过滤用户是招商总同时是业务员的用户
        if(!CollectionUtil.isEmpty(result)){
            ResponseEntity<ResultObject> entity = authorityClient.getUserByStationIdAndOrg(stationId,orgIds,"merchantsTotal");
            if(entity != null){
                if(entity.getStatusCode().is2xxSuccessful()){
                    Object results = entity.getBody().getResults();
                    List<Map> maps = JSON.parseArray(JSON.toJSONString(results),Map.class);
                    if(!CollectionUtil.isEmpty(maps)){
                        result = result.stream().filter(d1 -> maps.stream().noneMatch(d2 -> Objects.equals(d1.get("userId"),d2.get("userId"))))
                                .collect(Collectors.toList());
                    }
                }
            }
        }
        return result;
    }

    /**
     * @Description 查询当前登录人的组织(部门)以及子组织（部门）
     * @Param Long userId
     * @Return List<Long>
     * @Date 2021/5/12 15:09
     */
    private List<Long> subOrg(Long userId) {
        List<Long> orgIds = new ArrayList<>();
        String orgIdStr = redisClient.get("Org:" + userId);
        //获取当前登录人的组织
        if(!StringUtil.isEmpty(orgIdStr)){
            //查询当前组织以及子组织信息
            ResponseEntity<ResultObject> responseEntity = authorityClient.getSubOrg(orgIdStr);
            if(responseEntity != null){
                if(responseEntity.getStatusCode().is2xxSuccessful()){
                    Object results = responseEntity.getBody().getResults();
                    List<Organization> organizations = JSON.parseArray(JSON.toJSONString(results),Organization.class);
                    if (!CollectionUtil.isEmpty(organizations)) {
                        orgIds = organizations.stream().filter(organization -> organization.getId() != null)
                                .map(Organization::getId).collect(Collectors.toList());
                    }
                }
            }
        }
        return orgIds;
    }
}
